package Tier2;

import Shared.*;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;

import javax.ws.rs.core.MultivaluedMap;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.transform.stream.StreamSource;

import java.io.StringReader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Réceptionne les actions des clients et les envoit au partyManager. <br>
 * 
 * Pour modifier PartyManager : ORB_PartyManager/ORB_PartyManager.idl,
 * RMI_PartyManager/PartyManager.java, PartyManagerImpl.java
 * 
 * Pour modifier la BD : UserManager.java
 */
public class Serveur {

    private static WebResource db = null;

    /**
     * Constructeur :
     * Initialisation de la BD
     */
    public Serveur() {
	 //Initialisation du stub pour interagir avec le service web REST
	db = Client.create().resource("http://" + _Config.REST_host + ":" + _Config.REST_port + "/" + _Config.user_manager);
    }

    /**
     * Liste les joueurs connus de la BD
     * @return Players (classe contenant une liste de Player)
     * @throws Exception
     */
    private static Players _listerPlayers() throws Exception {    
	String request = db.path("listerPlayers").get(String.class);
	       
	//Definit un convertiseur XML => Objet Java
	JAXBContext context = JAXBContext.newInstance(Players.class); 
	Unmarshaller unmarshaller = context.createUnmarshaller();

	//Traite la reponse XML => Players
	StringBuffer xmlStr = new StringBuffer(request);
	JAXBElement<Players> root = unmarshaller.unmarshal(new StreamSource(new StringReader(xmlStr.toString())), Players.class);
	    
	return root.getValue();
    }
    public Players listerPlayers() {
    	try { return _listerPlayers();}
    	catch (Exception e) {e.printStackTrace();}
		return new Shared.Players();
    }
    
    /**
     * Ajoute un joueur à la BD
     * @return faux s'il existe dejà (objet)
     * @throws Exception
     */
    private static boolean _addPlayer(Player p) throws Exception {
	String result = db.path("addPlayer").put(String.class, p);
	return (result.contentEquals("true") ? true : false);
    }
    public boolean addPlayer(Player p){
	try { return _addPlayer(p); } catch (Exception e) { e.printStackTrace(); }
	return false;
    }
    
    /**
     * Ajoute un joueur à la BD
     * @param String name, String password
     * @return true si le player a été créé
     * @throws Exception
     */
    private static boolean _createPlayer(String name, String password){
    	MultivaluedMap<String, String> params = new MultivaluedMapImpl();
    	params.add("name", name);
    	params.add("password", password);
    	
    	Player player = db.path("createPlayer").queryParams(params).put(Player.class);
    	return (player.getName().isEmpty() ? false : true);
 	   
    }
    public boolean createPlayer(String name, String password){
    	try {  return _createPlayer(name, password); } catch(Exception e) { e.printStackTrace(); }
    	return false;
    }
    
    /**
     * Fonction internet - connecte un joueur à l'application
     * @param Player player
     * @return true is le joueur existe et le mot de passe correspond.
     * @throws Exception
     */
    public static boolean _connectPlayer(String name, String password) throws Exception{
    	MultivaluedMap<String, String> params = new MultivaluedMapImpl();
    	params.add("name", name);
    	params.add("password", password);
    	
    	Player p = db.path("checkAuth").queryParams(params).put(Player.class);
    	return (p.getName().isEmpty() ? false : true);
    }
    public boolean connectPlayer(String name, String password) {
	try { return _connectPlayer(name, password); } catch(Exception e) { e.printStackTrace(); }
	return false;
    }
    
    public Player _getPlayer(String name) throws Exception {
			Players players = _listerPlayers();
			for(Player p : players.liste){
				if(p.getName().contentEquals(name)) {
					return p;
				}
			}
			return new Shared.Player(); 
			
	}
    public Player getPlayer(String name) { 
    try { return _getPlayer(name); } catch (Exception e) { e.printStackTrace(); } 
    return new Shared.Player();  }
    
    //Juste pour tester Glassfish
    public static void main(String args[]) throws Exception {	
	       db = Client.create().resource("http://" + _Config.REST_host + ":" + _Config.REST_port + "/" + _Config.user_manager);
	       //_addPlayer(new Player("D"));
	       _connectPlayer("florent", "azerty");
	       System.out.println("done");
	       
	       Players players = _listerPlayers();
	       for(int i = 0; i < players.liste.size(); i++) {
	          System.out.println(players.liste.get(i).getName()+"-"+players.liste.get(i).get_password());
	       } 
    }
}